Repository navigation
fix: allow unquoted names DuckDB reserves but Snowflake doesn't - #482
Open
THEtheChad wants to merge 5 commits into
Open
THEtheChad wants to merge 5 commits into
THEtheChad wants to merge 5 commits into
Conversation
A table or column named with an unquoted word such as SEMI, PIVOT, LAMBDA or VERBOSE failed with a DuckDB parser error. Snowflake doesn't reserve these words, so it creates and reads such tables and columns. DuckDB does reserve them, and sqlglot's DuckDB generator only quotes the reserved words in its own list, which misses many (SEMI, ANTI, POSITIONAL, SIMILAR, OVERLAPS, FREEZE, VERBOSE, ASOF and CONCURRENTLY, even in sqlglot 30.25.0). Generate DuckDB SQL with a DuckDB dialect that quotes every identifier DuckDB can't take unquoted, taking the words from DuckDB's own duckdb_keywords() (the reserved and type_function categories), so the list matches the installed DuckDB. Statements and COPY INTO inserts are generated with it. Names are already upper-cased before generation and DuckDB matches quoted identifiers case-insensitively, so names resolve as before. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Use the DuckDB dialect for the internal SELECT-star description. Split reserved-name operation tests so each result is checked independently, and cover column renaming and preservation of quoted case. Co-Authored-By: GPT-6 Astra <noreply@openai.com>
THEtheChad
added a commit
to THEtheChad/fakesnow
that referenced
this pull request
Oct 27, 2026
# Conflicts: # fakesnow/transforms/transforms.py # tests/test_fakes.py # tests/test_server.py
Quoting every word DuckDB reserves also quoted words Snowflake reserves in every context. DuckDB's list adds by, check, create, group, ilike, in, is, like, null, qualify and tablesample, and quoting them made fakesnow accept statements such as create table example (qualify int) or create table group (x int). Snowflake rejects these, and fakesnow rejected them before because DuckDB did. Leave Snowflake's documented reserved keywords (the ones reserved by ANSI or by Snowflake, https://docs.snowflake.com/en/sql-reference/reserved-keywords) out of the extra quoting, so DuckDB rejects them as it did before. Words Snowflake reserves only in some contexts, such as asof, lateral or left, stay quoted, because Snowflake accepts them as column names. sqlglot's Snowflake dialect has no reserved-keyword list to reuse. Checked against a live Snowflake account (10.38): each of the 11 words is rejected with 001003 (42000) in create table <word> (x int) and create table example (<word> int). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Quote schema-derived CTAS columns and Parquet field references so excluding Snowflake-reserved keywords cannot turn NULL into a literal or reject QUALIFY. Add four regression cases and document manual keyword-list maintenance. Checked against live Snowflake 10.38.102: typed CTAS and Parquet COPY preserve values for NULL and QUALIFY (COPY via an internal stage). Co-Authored-By: GPT-6 Astra <noreply@openai.com>
THEtheChad
added a commit
to THEtheChad/fakesnow
that referenced
this pull request
Oct 27, 2026
THEtheChad
added a commit
to THEtheChad/fakesnow
that referenced
this pull request
Oct 27, 2026
On the fork's main, the reserved-word quoting (tekumara#482) and the follow-ups to tekumara#471 and tekumara#473 make those cases match Snowflake, so their marks are gone. The keywords that still differ cite the sqlglot issues behind them (tobymao/sqlglot#8804, #8805); tekumara#482 also makes fakesnow accept QUALIFY, ILIKE and TABLESAMPLE as column names in CREATE TABLE, which Snowflake refuses, so those are marked like UNION and SAMPLE. The LOCALTIMESTAMP and DATE_TRUNC cases cite tobymao/sqlglot#8807 and #8806. Newly marked after the live run, each checked against Snowflake: TRIM and its variants ignore the characters to remove, MERGE doesn't detect a target row matched twice, the in-process PUT result is described as one column, and a VARCHAR(n) column's result metadata loses n. A mark that had landed on ddl.describe-table belongs to ddl.show-schemas. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
THEtheChad
added a commit
to THEtheChad/fakesnow
that referenced
this pull request
Oct 27, 2026
QUALIFY, ILIKE and TABLESAMPLE as unquoted column names are refused again on fork main, as Snowflake refuses them, so the live run reported their marks as now matching. Removes the marks and their pinned fingerprints. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
typos read "pIvOt" as a misspelling of "to"; "PiVoT" is still a quoted mixed-case PIVOT. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #481.
Unquoted table and column names such as
semi,pivotandverbosework in Snowflake but failed with a DuckDB parser error. sqlglot's DuckDB generator already quotes known reserved words, but its list is incomplete (reported as tobymao/sqlglot#8804; 30.25.0 addedPIVOT,UNPIVOT,LAMBDAandSUMMARIZE, but not the rest).reservedandtype_functioncategories fromduckdb_keywords(), read once through a short-lived in-memory connection at import. The customFakesnowDuckDBdialect registers separately and does not modify sqlglot'sduckdbdialect.by,check,create,group,ilike,in,is,like,null,qualifyandtablesamplerejected as unquoted table and column names. The Snowflake list is maintained manually because sqlglot's Snowflake dialect has no reserved-keyword list to reuse.SELECT *in typed CREATE TABLE AS. Explicitly quote column references synthesized from DESCRIBE results and Parquet field names, so names such as"NULL"and"QUALIFY"retain their values in CTAS and COPY transformations.Tests cover the affected words as table and column names, metadata casing, quoted lookup and mixed case, ALTER/DROP, UPDATE/DELETE/MERGE, CTEs and aliases, typed CREATE TABLE AS, COPY INTO, and server mode. Another 22 cases check rejection of the 11 Snowflake-reserved words; four cases preserve quoted reserved column names in CTAS and Parquet COPY transformations.
Some accepted Snowflake syntax still fails earlier in sqlglot's Snowflake parser (reported as tobymao/sqlglot#8805):
returningandglobas table names or column referencesconcurrentlyas a table nameselect using from tcreate table t (exclude int)select lateral from tdescribe table pivotALTER TABLE pivot RENAME COLUMN semi TO antiworks and is covered by a test.This does not add Snowflake keyword validation. Context-dependent words remain quoted in all contexts: Snowflake accepts
asof,left,right,fullandnaturalas column names and in CREATE TABLE, but requires quotes around these table names in a SELECT's FROM clause. fakesnow also accepts those unquoted SELECTs, consistent with the README's existing caveat about accepting a more liberal dialect. Existing differences forsome,minus,increment,regexpandrlikeremain outside this change.Checked against a live Snowflake account (10.38): the #481 examples and new positive test cases, including rename and typed CREATE TABLE AS; error 001003 (42000) for all 22 reserved-name rejection cases; and preserved values for
"NULL"/"QUALIFY"in typed CTAS and Parquet COPY transformations (using an internal stage for the live COPY check).🤖 Generated with Claude Code